#ifndef GM3LAYOUT_H   //#ifndef LAYOUT_H
#define GM3LAYOUT_H  //#define LAYOUT_H

#include "GM3Graph.h"  //#include "Graph.h"
#include "cvec.h"

#include <CL/cl.h>

#include <vector>
#include <string>

//namespace GM3{

class GM3Layout
{
    public:
        static const char delim = '\t';

        //general
        static float initialT; //initial temperature for all levels
        static int coarsestSteps; //steps at the coarsest level of the graph
        static int finestSteps; //steps at the finest (original) level
        static float lambda; //temperature reduction
        static float eta; //softening (eliminates divide-by-0)
        static float repConst;
        static float desLength; //desired spring length

        //multi-level
        static unsigned int coarseningThresh; //maximum top-level graph size
        static float desLengthDecay;
        static float initialTDecay;

        //multi-pole
        static float theta; //threshold angle for approximation
        static float err; //percent allowed relative error in approximation
        static float omega; //r_c/r threshold for approximation
                            // DON'T SET MANUALLY

        //multiple timestep
        static float correlatingConst;


        GM3Layout(const char *fn=0);
        GM3Layout(GM3Graph *);

        virtual ~GM3Layout();

        void loadFile(const char *fn=0);
        virtual void loadGraph(GM3Graph *, unsigned int N=0, unsigned int E=0, bool ifRandomize=false);

        //accessors
        inline GM3Graph *g(){ return !graphList.empty() ? &(*currGraph) : NULL; }
        inline GM3Graph *graph(int level=0)
        { return !graphList.empty() ? &(graphList[level]) : NULL; }

        inline unsigned int height(){ return graphList.size(); }

        void boundingBox(float &x0, float &y0, float &x1, float &y1);

        void randomize();
        void randomizeAll();

        // KD tree building operates on currGraph
        void buildKDTree();
        void buildKDTree(unsigned int graphLvl);
        void buildKDTree(unsigned int graphLvl, unsigned int thresh);

        void rescaleAll();
    protected:
        std::vector<GM3Graph> graphList;
        std::vector<GM3Graph>::iterator currGraph;

        //These values are kept for doing user-controlled layout
        unsigned int currStep;
        float currT; //temperature

#ifdef TIME_ACC
        double tdiff(timespec, timespec);
#endif

        //graph initialization
        void buildReductions();

};

//}

#endif
